﻿package {
	import flash.display.*;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.KeyboardEvent;
	import flash.net.URLRequest;
	import flash.text.*;
	//import fl.controls.TextField;
	
	/** Can be used as either a question or answer in a multiple choice item 
	*  Or as a static display in a Presentation
	*  Or as a wrapper for a TextInput in a free response test
	*/
	
	public class TextImageDisplay extends MovieClip{
		private const Y_BORDER_PADDING:int = 20;
		private const X_BORDER_PADDING:int = 20;
		private const Y_LINE_PADDING:int = 5;
		public var showNum:Boolean = false;
		public var item_number:int;
		public var id:String;
		public var title:String;
		public var justify:String = "center";
		private var numberTextField:TextField;  // if this is null, following MUST be null
		private var numberTextImageLine:TextImageLine; // and vice-versa
		private var ldr:Loader;
		private var tImage:TextImageLine;
		private var tfield:TextField;
		private var tarea:TextField;
		private var totalItems:int, currentItem:int;
		private var WIDTH:int, HEIGHT:int, maxWidth:int = 0;
		private var xml:XML;
		private var currentY:int = Y_BORDER_PADDING;
		private var myTextFormat:TextFormat;
		private var currentEvent:KeyboardEvent;
		
		public function TextImageDisplay (){			
			myTextFormat = new TextFormat("Arial", 16, 0x000000,null,null,null,null,null,TextFormatAlign.LEFT, null, null, null, Y_LINE_PADDING);
		}
		
		public function load(xml:XML, WIDTH:int, HEIGHT:int, item_number:int=-1, drawBorder:Boolean=true):void
		{
			this.xml = xml;
			this.item_number = item_number;
			if (xml.attribute("id").length() > 0) { this.id = String(xml.attribute("id")[0]); } else { id = "-1";}
			if (xml.attribute("justify").length() > 0) { this.justify = String(xml.attribute("justify")[0]); } else { justify = "center";}
			this.WIDTH = WIDTH;
			this.HEIGHT = HEIGHT;
			if (drawBorder) this.graphics.lineStyle(2,0x000000);
			////////////////////// add conditional
			if (this.HEIGHT > 0)
			{
				this.graphics.beginFill(0xFFFFFF);
				this.graphics.drawRect(0,0,WIDTH,HEIGHT);
				this.graphics.endFill();
			}
			totalItems = xml.child("*").length();
			currentItem = 0;
			addNewItem();
		}
		/** Add the current item in the list of children */
		private function addNewItem():void
		{
			/// Iterate through each child
			var child:XML = xml.child("*")[currentItem];
			if(child.name() == "text"){
				tfield = new TextField();
				tfield.multiline = true;
				tfield.wordWrap = true;
				tfield.selectable = false;
				tfield.mouseEnabled = false;
				tfield.width = WIDTH-2*X_BORDER_PADDING;
				tfield.defaultTextFormat = myTextFormat;
				tfield.text = String(child).split("[n]").join("\n ");
				tfield.text = tfield.text.split("[t]").join("     ");
				if (child.attribute("showNum").length() > 0 && child.attribute("showNum")[0] == "true"){
					tfield.text = String(item_number + ".) " + tfield.text);
				} 
				//tfield.autoSize = justify;
				//tfield.height = tfield.getLineMetrics(0).height*tfield.numLines;	
				tfield.height = tfield.textHeight + 4;
				tfield.width = tfield.textWidth + 8;
				//trace("heights", tfield.textHeight, tfield.numLines, tfield.height);
				if (tfield.width > maxWidth) maxWidth = tfield.width;
				////////////////////// CHANGE this.width to WIDTH
				if (justify == "center") tfield.x = (this.WIDTH - tfield.width)/2;
				tfield.y = currentY;
				currentY += tfield.textHeight + Y_LINE_PADDING;
				this.addChild(tfield);
				completeNewItem();
				// Is this a complex line of image and text?
			}else if (child.name() == "timg"){
				tImage = new TextImageLine();
				tImage.addEventListener(Event.COMPLETE, handleLoadedTIMG);
				try {
					tImage.load(child, item_number);
				} catch (e:IOErrorEvent){
					tImage.removeEventListener(Event.COMPLETE, handleLoadedTIMG);
					trace(String(xml..timg), " does not exist.");
				}
			} // Is this a simple image? 
			 else if (child.name() == "img"){
				ldr = new Loader();
				//trace(String("images/"+child));
				var urlReq:URLRequest = new URLRequest(String("images/"+child));
				ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, handleLoadedIMG);
				try {
					ldr.load(urlReq);
				} catch (e:IOErrorEvent){
					ldr.contentLoaderInfo.removeEventListener(Event.COMPLETE, handleLoadedIMG);
				trace(String(child), " does not exist.");
				}				
			}
			else if (child.name() == "tinput"){
				tarea = new TextField();
				tarea.defaultTextFormat = myTextFormat;
				tarea.text = "here";
				if (child.attribute("maxChars").length() > 0){ tarea.maxChars = int(child.attribute("maxChars")[0]); } else { tarea.maxChars = 1}
				////////////////////// CHANGE this.width to WIDTH
				tarea.width = this.WIDTH - 2*X_BORDER_PADDING;
				tarea.height = Math.ceil(tarea.maxChars/(tarea.width/int(myTextFormat.size))) * int(myTextFormat.size) * 1.5;
				////////////////////// CHANGE this.width to WIDTH
				if (justify == "center") tarea.x = (this.WIDTH - tarea.width)/2;
				tarea.y = currentY;
				this.addChild(tarea);
				completeNewItem();
			}
		}
		public function get static_height():int{return HEIGHT}
		public function get static_width():int{return WIDTH}
		/** In the case where we need to show a number this function adds a given number to the front of the text */
		
		private function handleLoadedIMG (event:Event):void
		{
			ldr.contentLoaderInfo.removeEventListener(Event.COMPLETE, handleLoadedIMG);
			ldr.mouseEnabled = false;
			this.addChild(ldr);
			if (justify == "center") ldr.x = (this.width - ldr.width)/2;
			if (ldr.width > maxWidth) maxWidth = ldr.width;
			ldr.y = currentY;
			currentY += ldr.height + Y_LINE_PADDING;
			completeNewItem();
		}
		private function handleLoadedTIMG (event:Event):void
		{
			tImage.removeEventListener(Event.COMPLETE, handleLoadedTIMG);
			tImage.mouseEnabled = false;
			this.addChild(tImage);
			if (justify == "center") tImage.x = (this.width - tImage.width)/2;
			//tImage.x = X_BORDER_PADDING;
			if (tImage.width > maxWidth) maxWidth = tImage.width;
			tImage.y = currentY
			currentY += tImage.height + Y_LINE_PADDING;
			// Is this the top line, then it can hold the number
			if (numberTextField == null && numberTextImageLine == null){
				showNum = true;
				numberTextImageLine = tImage;
			}
			completeNewItem();
		}
		// Either add another item, or arrange these items horizontally and dispatch complete event
		private function completeNewItem():void
		{
			var i:int;
			currentItem++;
			if (currentItem < totalItems){
				addNewItem();
			} else {
				// justify left
				var init_X:Number = (this.width - maxWidth)/2;
				if (justify == "left"){
					for (i=0; i < this.numChildren; i++){
							this.getChildAt(i).x = init_X;
					}
				} else if (justify == "right"){
					for (i=0; i < this.numChildren; i++){
							this.getChildAt(i).x = init_X + (maxWidth - this.getChildAt(i).width);
					}
				}
				if (this.HEIGHT == 0)
				{
					this.graphics.beginFill(0xFFFFFF);
					this.graphics.drawRect(0,0,WIDTH,this.height);
					this.graphics.endFill();
			
					this.HEIGHT = this.height;
				}
				this.dispatchEvent(new Event(Event.COMPLETE));
			}
		}
		public function highlight(color:uint=0xCCCCCC):void
		{
			this.graphics.clear();
			this.graphics.lineStyle(2,0x000000);
			this.graphics.beginFill(color);
			this.graphics.drawRect(0,0,WIDTH,HEIGHT);
			this.graphics.endFill();
		}
		public function select(color:uint=0xAAAAAA):void
		{
			this.graphics.clear();
			this.graphics.lineStyle(2,0x000000);
			this.graphics.beginFill(color);
			this.graphics.drawRect(0,0,WIDTH,HEIGHT);
			this.graphics.endFill();
		}
			
		public function clear():void
		{
			this.graphics.clear();
			this.graphics.lineStyle(2,0x000000);
			this.graphics.beginFill(0xFFFFFF);
			this.graphics.drawRect(0,0,WIDTH,HEIGHT);
			this.graphics.endFill();	
		}
		/******* The following functions are for a TextInput, dispatches the event */
		private function handleKeyboardEvent(event:KeyboardEvent):void
		{
			currentEvent = event;
			this.dispatchEvent(event);
		}
		public function get text():String
		{
			if (tarea != null){
				var _text:String = tarea.text;
				return _text;
			} 
			return ("");
		}
	}
}